use std::{fs::create_dir_all, path::PathBuf};

use datasource_connector::connector::SimpleDataSourceConnector;
use model_graph_common::utils::{
    new_uuid, read_bytes_from_pathbuf, rrg01_home_path, zip::extract_v8_to_fs,
};
use model_graph_types::{
    database::{ConnectorProtocol, DataSource, DatabaseType},
    datasource::{DataSourceConnector, QueryCondition},
    modeling::{ClassGetter, Domain, Value},
    transform::{DomainTransformerOptions, DomainTransformerUnit},
};

/// 领域数据转移
pub async fn import_domain_from_file(
    source: &String,
    target: &DataSource,
    domains: &DomainTransformerUnit,
    options: &DomainTransformerOptions,
) -> anyhow::Result<()> {
    //
    let home_path = format!(
        "{}",
        rrg01_home_path()
            .map_err(|err| anyhow::anyhow!("获取程序目录失败:{}", err))?
            .to_str()
            .map_or(Err(anyhow::anyhow!("获取程序目录失败")), |v| Ok(v))?
    );
    //创建导出的临时目录
    tracing::debug!("创建临时目录");
    let export_path = format!("{}/temp/{}/", home_path, new_uuid()?);
    let _ = create_dir_all(&export_path);
    let source_sqlite_file = format!("{}/domain.sqlite", &export_path);
    //解压文件

    tracing::debug!("解压文件");
    let zip_pathbuf = PathBuf::from(source);
    let zip_file: Vec<u8> = read_bytes_from_pathbuf(&zip_pathbuf)?;
    extract_v8_to_fs(&zip_file, export_path.as_str())?;

    //创建源数据源
    let source_datasource = DataSource {
        database_type: DatabaseType::SQLite,
        protocol: ConnectorProtocol::SQLite,
        url: source_sqlite_file.clone(),
        ..Default::default()
    };
    tracing::debug!("查询解压后的文件的所有需要导入的领域");
    //
    let values = SimpleDataSourceConnector::default()
        .instance_query(
            &None,
            &source_datasource,
            &Domain::get_identifier()?,
            QueryCondition::default(),
            None,
            None,
        )
        .await?
        .data;
    tracing::debug!("所有导入的domains:{:?}", values);

    for d in values {
        let mut item = domains.clone();
        // let domain: Domain = d.try_into()?;
        if let Some(Value::String(identifier)) = d.value_from_key(&String::from("identifier")) {
            item.domain_identifier = identifier.clone();
        } else {
            continue;
        }
        tracing::debug!("domain:{}", item.domain_identifier);

        super::domain_transform(&source_datasource, target, &item, options).await?;
    }
    //涉及到的一些文件进行拷贝
    //1. 特性流程文件

    Ok(())
}
